﻿//Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@fin-plus.co.uk website <http://www.fin-plus.co.uk/>
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Windows.Controls;
using FinPlusAssembler;
using FinPlusInterfaces;

namespace FinPlusCompView
{
    public partial class FinPlusFilterbarTray : FinPlusControl
    {
        [State(Test = true)]
        public override bool IsValid { get; set; }
        [State(Save = true)]
        public new double Height { get { return base.Height; } set { base.Height = value; } }
        [State(Save = true)]
        public new double Width { get { return base.Width; } set { base.Width = value; } }
        [State(Test = true)]
        public override string TestString { get { return Adapter.ToString(); } }
        [State(Test = true)]
        public ConcurrentDictionary<string, FinPlusFilterbar> FilterOut { get { return _filterOut; } }
        [State(Test = true)] 
        public int ChildrenCount { get { return stackPanel.Children.Count; } }      
        public override IPods Adapter { get { return base.Children(stackPanel.Children); } }
        public string Filterbars
        {
            get
            {
                return _filterOut.Select(x => x.Key).ToArray().StringFrom1d(',', "{}");
            }
            set
            {
                foreach (string filterbar in value.ToArray1d(',', "{}"))
                    AddFilterbar(new FinPlusFilterbar(filterbar));
            }
        }
        public string FilteredOut
        {
            get
            {
                var f = (Dictionary<string, string[]>)_filterOut.ToDictionary(k => k.Key, k => k.Value.FilterOut.Select(x => x.ToString()).ToArray());
                return f.DictToString(',', "{}");
            }
            set
            {
                var f = value.ToDictOfArrays(',', "{}");
                if (f != null)
                    foreach (var filterbar in f)
                        _filterOut[filterbar.Key.ToString()].FilterOut = filterbar.Value.Select(x => (object)x).ToList();
            }
        }
        public event EventHandler<IPod> FilterUpdate;
         
        private enum DockControls { FinPlusFilterbar, FinPlusConnectService, Default }
        private ConcurrentDictionary<string, FinPlusFilterbar> _filterOut = new ConcurrentDictionary<string, FinPlusFilterbar>();
        private IDPods _dPods = null;

        //construct
        public FinPlusFilterbarTray()
        {
           InitializeComponent();
           IsValid = true;
        }

        //common control interface
        public override void Dock(object control, string dock)
        {
            try
            {
                switch (control.GetType().Name.EnumParse<DockControls>(DockControls.Default))
                {
                    case DockControls.FinPlusFilterbar: AddFilterbar((FinPlusFilterbar)control); break;
                    case DockControls.FinPlusConnectService: AddConnection(((FinPlusConnectService)control).DPods()); break;
                    case DockControls.Default: stackPanel.Children.Add((UserControl)control); break;
                }
            }
            catch (Exception e)
            {
                IsValid = Level.Warning.Log(Id, Config, e.Message, e);
            }
        }

        public override void CmdExecute(IPod command)
        {
            try
            {
                CmdCapture(command);

                switch ((Cmds)Enum.Parse(typeof(Cmds), command.Name, true))
                {
                    case Cmds.Refresh: Refresh(command); break;
                    default: throw new Exception(string.Format("cmd not recognised {0}", command.Name));
                }
            }
            catch (CmdExecuteException e)
            {
                IsValid = Level.Warning.Log(Id, Config, e.Message, e);
            }
        }

        //public 
        public bool HasFilterbar(string name)
        {
            return _filterOut.ContainsKey(name);
        }

        public void AddConnection(IDPods _conn)
        {
            try
            {
                _dPods = _conn;
            }
            catch (Exception e)
            {
                Level.Error.Log(Id, Config, e.Message, e);
            }
        }

        public void AddFilterbar(FinPlusFilterbar filterbar)
        {
            try
            {
                RemoveFilterbar(filterbar.Name);
                _filterOut[filterbar.Name] = filterbar;
                filterbar.AddViewSource(_dPods, Filter_Callback);
                stackPanel.Children.Add(filterbar);
            }
            catch (Exception e)
            {
                Level.Error.Log(Id, Config, e.Message, e);
            }
        }

        public void RemoveFilterbar(string name)
        {
            try
            {
                FinPlusFilterbar f = null;
                if (_filterOut.ContainsKey(name) && _filterOut.TryRemove(name, out f))
                {
                    stackPanel.Children.Remove(f);
                    Filter_Callback();
                }
            }
            catch (Exception e)
            {
                Level.Error.Log(Id, Config, e.Message, e);
            }
        }

        //private
        private int Count()
        {
            return _dPods.Count();
        }

        private bool Refresh(IPod pod)
        {
            FilterUpdate.Invoke(this, pod);
            return true;
        }

        //cmds
        private enum Cmds { Refresh }

        //events
        private void Filter_Callback() { CmdRouter(Cmds.Refresh.ToString()); }
    }
}
